package pl.enigmatic.objects;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;


/**
 * <code>class</code> extending {@link java.util.Properties} to serve more utility methods to simplify thigs
 * 
 * @author reggie_7
 * 
 */
public class Properties extends java.util.Properties {

	private static final long serialVersionUID = 1L;

	/**
	 * <code>URL</code> representing properties file location for properties saving purposes
	 */
	protected URL url = null;

	/**
	 * default constructor
	 */
	public Properties() {}

	/**
	 * default constructor
	 */
	public Properties(final Properties p) {
		super(p);
	}

	/**
	 * constructor initializing values from input stream
	 * 
	 * @param is input stream with properties file
	 */
	public Properties(final InputStream is) {
		this();
		try {
			load(is);
		} catch (final Exception e) {}
	}

	/**
	 * sets <code>url</code>
	 * 
	 * @param url new <code>URL</code>
	 */
	public void setUrl(final URL url) {
		this.url = url;
	}

	/**
	 * @return <code>url</code> of the file for saving purposes
	 */
	public URL getUrl() {
		return url;
	}

	public boolean save() {
		// TODO needs to be corrected
		if (url != null) {
			try {
				final FileOutputStream fos = new FileOutputStream(url.toURI().toString());
				storeToXML(fos, "");
				fos.flush();
				fos.close();
				return true;
			} catch (final Exception e) {}
		}
		return false;
	}

	/**
	 * sets the value associated to given key to the given one
	 * 
	 * @param key unambiguos key
	 * @param value value associated to the key given
	 * @return <code>true</code> if there was a value associated to this key before
	 */
	public boolean set(final String key, final int value) {
		final boolean res = containsKey(key);
		setProperty(key, Integer.toString(value));
		return res;
	}

	/**
	 * tries to parse value associated to the given <code>key</code> to <code>int</code>
	 * 
	 * @param key key defining required value
	 * @return stored <code>int</code> value associated to given <code>key</code>, or <code>0</code> if there is none
	 */
	public int getInt(final String key) {
		try {
			final String s = getProperty(key, "0");
			return Integer.parseInt(s);
		} catch (final Exception e) {
			return 0;
		}
	}

	/**
	 * sets the value associated to given key to the given one
	 * 
	 * @param key unambiguos key
	 * @param value value associated to the key given
	 * @return <code>true</code> if there was a value associated to this key before
	 */
	public boolean set(final String key, final String value) {
		final boolean res = containsKey(key);
		setProperty(key, value);
		return res;
	}

	/**
	 * gives <code>String</code> value associated to given <code>key</code>
	 * 
	 * @param key key defining required value
	 * @return stored value associated to given <code>key</code>, or empty <code>String</code> if there is none
	 */
	public String getString(final String key) {
		return getProperty(key, "");
	}

	/**
	 * sets the value associated to given key to the given one
	 * 
	 * @param key unambiguos key
	 * @param value value associated to the key given
	 * @return <code>true</code> if there was a value associated to this key before
	 */
	public boolean set(final String key, final boolean value) {
		final boolean res = containsKey(key);
		setProperty(key, Boolean.toString(value));
		return res;
	}

	/**
	 * gives <code>boolean</code> value associated to given <code>key</code>
	 * 
	 * @param key key defining required value
	 * @return stored <code>boolean</code> value associated to given <code>key</code>, or <code>false</code> if there is none, or the value held is
	 *         incorrect (different from "false" or "true" with case ignored)
	 */
	public boolean getBoolean(final String key) {
		try {
			final String s = getProperty(key, "false");
			return Boolean.parseBoolean(s);
		} catch (final Exception e) {
			return false;
		}
	}

}
